package com.lxk.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lxk.pojo.Users;
import com.lxk.service.LoginService;
import com.lxk.service.UsersService;
import com.lxk.util.HttpUtil;
import com.lxk.util.weixin.WeChatUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * @author JohnSoybean
 * @create 2020/7/24 15:10
 * @description 微信H5登录
 */
@Controller
@RequestMapping("/web")
@Slf4j
public class LoginWebController {

    @Autowired
    private UsersService usersService;
    @Autowired
    private LoginService loginService;


    /**
     * 微信网页授权：
     * 1. 重定向到微信获取CODE，
     * 2. 由CODE获取access_token和openid
     *
     * @param request
     * @param Url     授权之后将要跳转的页面,为前端的外部链接
     */
    @RequestMapping("/oauth2")
    public String oauth2Code(HttpServletRequest request, @RequestParam String Url) {
        System.out.println("##########################################################");
        String backUrl = "";// 要返回的url
        // 查看将要跳转的页面是否以http或者https开头
        if (Url.startsWith("http://") && Url.startsWith("https://")) {
            backUrl = Url;
        } else {
            String requestUrl = WeChatUtil.server_url;
            if (request.getContextPath() != null && !request.getContextPath().equals("")) {
                // 如果有项目名，拼接项目名
                requestUrl += request.getContextPath();
            }
            // 最后拼接，URLEncoder微信接口指定需用此方法格式化url
            try {
                backUrl = URLEncoder.encode(requestUrl + "/web/oauth2AccessToken?targetUrl=" + Url, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        // 格式化最后需要请求的路径
        String redirectUrl = String.format(WeChatUtil.snsapi_url, WeChatUtil.appid_H5, backUrl, WeChatUtil.snsapi_userinfo,
                WeChatUtil.getNonceStr());
        return "redirect:" + redirectUrl;
    }


    /**
     * 1. 根据code获取 access_token和openid
     * 2. 根据这两项拉取用户信息
     *
     * @param request
     * @param code
     * @param targetUrl
     * @return
     */
    @RequestMapping(value = "/oauth2AccessToken", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
    public String oauth2OpenId(HttpServletRequest request, String code,
                               @RequestParam String targetUrl) {

        System.out.println("##########################################################");
        //判断是否带参数
        int index = targetUrl.indexOf("?");
        String returnParam = null;

        if (code == "" || code == null) {
            returnParam = index < 0 ? "?msg=AuthFailed" : "&msg=AuthFailed";
            return "redirect:" + targetUrl + returnParam;
        }
        // 根据上一步获取的code获取网页授权用户的access_token和openid
        JSONObject json = WeChatUtil.getAccessTokenOauth2(code);
        log.info(json.getString("access_token"));
        // 根据上一步的access_token和openid获取用户信息
        JSONObject userinfo = HttpUtil.doGet(String.format(WeChatUtil.userinfo_url, json.getString("access_token"), json.getString("openid")));
        log.info("JSONObject:" + userinfo);
        //获取unionid
        String openid = json.getString("openid");
        String unionid = userinfo.getString("unionid");
        //TODO 暂无unionid，将openid伪造成unionid
        if (null == unionid || unionid.equals("")) {
            unionid = "UN:" + openid;
        }
        //判断是否为新用户,并处理业务逻辑
        String token = "";
        Users users = usersService.getOne(new LambdaQueryWrapper<Users>().eq(Users::getUnionid, unionid), false);
        if (users == null) {    //若用户不存在，新增用户
            Users newUser = new Users();
            newUser.setUnionid(unionid);
            newUser.setOpenidWeb(userinfo.getString("openid"));
            newUser.setUsername(userinfo.getString("nickname"));
            newUser.setHeadimg(userinfo.getString("headimgurl"));
            newUser.setSex(userinfo.getInteger("sex").toString());
            boolean save = usersService.save(newUser);
            if (!save) {
                returnParam = index < 0 ? "?msg=AuthFailed" : "&msg=AuthFailed";
                return "redirect:" + targetUrl + returnParam;
            }
            //返回token
            Long userId = newUser.getUserId();
            token = loginService.setAuth(userId);
        } else {    //用户存在，更新openidWeb
            //判断是否已被冻结
            if (users.getBlock() == 1) {
                returnParam = index < 0 ? "?msg=AccountBlocked" : "&msg=AccountBlocked";
                return "redirect:" + targetUrl + returnParam;
            }
            //更新openidWeb
            Users updUser = new Users();
            updUser.setUserId(users.getUserId());
            updUser.setOpenidWeb(openid);
            usersService.updateById(updUser);
            //返回token
            Long userId = users.getUserId();
            token = loginService.setAuth(userId);
        }
        //返回的url后添加userId信息
        //判断url中是否存在?
        returnParam = index < 0 ? "?token=" + token : "&token=" + token;
        return "redirect:" + targetUrl + returnParam;
    }


}
